package ApplicationLogic.controllers;

import java.util.List;

import businessLogic.model.AbstractModel;

import ApplicationLogic.modelMiscTools.IChildModelInsertor;
import ApplicationLogic.modelPersistence.IDAOTEMPLATE;
import ApplicationLogic.modelSerialization.IModelSerializer;
import ApplicationLogic.modelSerialization.ModelSerializer;
import ApplicationLogic.modelValidation.IModelValidator;




public class CRUDController extends AbstractController
{
		

	public CRUDController()
	{
		
	}

	
	public void Create(String XML) throws Exception
	{
		IDAOTEMPLATE dao = instancesPool.getDao();
		IModelSerializer modelSerializer = instancesPool.getmSerializer();
		IModelValidator modelValidator = instancesPool.getmValidator();
		
		AbstractModel Model = modelSerializer.getFirstObjectFromXML(XML);
		
		if (modelValidator.isValidModel(Model))
		{
			dao.createModel(Model);
		}
		else
		{
			String ValidationMessage = modelValidator.getNotValidModelMessage(Model);
			throw new Exception("Model isn't valid. Reason :"+ ValidationMessage);
		}
		
	}
	
	public void CreateChild(String XML, int ParentID, String ParentClass, String ParentFieldName) throws Exception
	{
				
		IDAOTEMPLATE dao = instancesPool.getDao();
		IModelSerializer modelSerializer = instancesPool.getmSerializer();
		IModelValidator modelValidator = instancesPool.getmValidator();

		AbstractModel parent = dao.getModelById(ParentID, Class.forName(ParentClass));
		AbstractModel newChildModel = modelSerializer.getFirstObjectFromXML(XML);
		
		//the child could be new or old. in the first case we use just the child reference
		//just created "child". Else, if we are injecting an old and known entity, we use child
		
		AbstractModel existingModel = dao.getModelById(newChildModel.getId(), newChildModel.getClass());
		
		AbstractModel childToInject;
		
		if (existingModel != null)
			childToInject = existingModel;
		else
			childToInject = newChildModel;
		
		IChildModelInsertor insertor = instancesPool.getChildModelInsertor();
		insertor.InsertNonPrimitiveAttributeIntoParent(parent, ParentFieldName, childToInject);
		
		//If the child model validates, we update the parent that now contains the child model
		if (modelValidator.isValidModel(childToInject))
		{
			dao.updateModel(parent);
		}
		else
		{
			String ValidationMessage = modelValidator.getNotValidModelMessage(childToInject);
			throw new Exception("Model isn't valid. Reason :"+ ValidationMessage);
		}
		
	}

	public String Read(String model, int Page) throws Exception
	{
		IDAOTEMPLATE dao = instancesPool.getDao();
		IModelSerializer modelSerializer = instancesPool.getmSerializer();
		
		try
		{
			List<AbstractModel> LModelos = dao.listModelByType(model,Page);
			
			
			String XMLReturn = modelSerializer.getXMLFromObjectList(LModelos,10);		
		
			return XMLReturn;
		}
		catch(Exception e)
		{
			throw e;	
		}
	}
	
	public void Update(String XML) throws Exception
	{
		IDAOTEMPLATE dao = instancesPool.getDao();
		IModelSerializer modelSerializer = instancesPool.getmSerializer();
		IModelValidator modelValidator = instancesPool.getmValidator();
		
		AbstractModel Model = modelSerializer.getFirstObjectFromXML(XML);
		
		if (modelValidator.isValidModel(Model))
		{
		dao.updateModel(Model);
		}
		else 
		{
			String ValidationMessage = modelValidator.getNotValidModelMessage(Model);
			throw new Exception("Model isn't valid. Reason :"+ ValidationMessage);
		}
		
	}

	public void Delete(String XML) throws Exception
	{
		IDAOTEMPLATE dao = instancesPool.getDao();
		IModelSerializer modelSerializer = instancesPool.getmSerializer();
		
		AbstractModel Model = modelSerializer.getFirstObjectFromXML(XML);
		
		try
		{
			dao.deleteModel(Model.getId(), Model.getClass());
		}
		catch (Exception e)
		{
			throw e;			
		}
		
	}


}
